feat: enhanced Discord thread management#215
Conversation
Adds `auto_archive_duration` to `DiscordConfig` with a default of 1440 (OneDay). Validates at config load time that the value is one of 60/1440/4320/10080. Passes the configured value through `Handler` to `get_or_create_thread` and converts it to the appropriate `AutoArchiveDuration` enum variant. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add per-channel configuration overrides via `[discord.channels."ID"]`
TOML sections. Each channel can independently override:
- require_mention: when false, any message triggers the bot (direct mode)
- ignore_other_mentions: skip messages mentioning other users/bots
- auto_archive_duration: per-channel thread archive duration
- thread_name_mode: per-channel thread naming strategy
New global defaults on DiscordConfig: require_mention (true),
ignore_other_mentions (false), thread_name_mode ("truncate").
Channel overrides fall back to global defaults when not set.
Validation of auto_archive_duration also applies to channel overrides.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use parent_channel_id (not thread ID) for per-channel config resolution - Remove unused effective_* methods from DiscordConfig (logic is inline in Handler) - Cache channel_override lookup to avoid repeated HashMap access Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When thread_name_mode is set to "generated" (global or per-channel), sends a short naming prompt to the ACP session after thread creation and renames the thread via Discord API before the main response. Falls back to the truncated name on any failure (timeout, error). Includes config validation for thread_name_mode values at load time. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Run LLM thread naming after main prompt completes in a tokio::spawn task instead of blocking before stream_prompt. This avoids: - Holding the pool write-lock during the naming request - Delaying the user's response while a name is generated - The naming prompt appearing before the user's real message in session history - Add "Do not use any tools" to naming prompt to prevent tool-use overhead - Strip quotes and markdown formatting from generated names Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… options - config.toml.example: add require_mention, ignore_other_mentions, thread_name_mode, and per-channel override examples - values.yaml: add discord.autoArchiveDuration, requireMention, ignoreOtherMentions, threadNameMode, and channels map - configmap.yaml: template per-channel config with range loop Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
This is a large feature with per-channel config, direct mode, and background thread naming. Could you please create a Discord discussion thread and add the link to this PR description? This helps with design review and community feedback for bigger features. Thanks! 🙏 |
chaodu-agent
left a comment
There was a problem hiding this comment.
🔴 STALE — Requires full rewrite against current architecture. Cannot merge.
Baseline Check (Step 0)
| Field | Value |
|---|---|
| State | OPEN |
| Mergeable | CONFLICTING |
| Created | 2026-04-11 (20 days ago) |
| Changes | +256 / -15 across 6 files |
| Labels | closing-soon |
Main branch status: Since April 11, main underwent major refactoring:
- AdapterRouter/ChatAdapter abstraction —
discord.rsnow uses trait-based adapter pattern - Handler struct completely different (new fields:
router,allow_all_channels,allow_bot_messages,trusted_bot_ids,bot_turns,participated_threads,multibot_threads,allow_dm) - Thread creation moved to
ChatAdaptertrait method shorten_thread_namemoved toformat.rs
Four-Question Framework
1. What problem does it solve?
Configurable thread management: auto-archive duration, require-mention toggle, ignore-other-mentions filter, LLM-generated thread names, per-channel config overrides.
2. How does it solve it?
- 4 new config fields + per-channel
ChannelConfigoverrides - Config validation at load time
generate_thread_name/request_thread_namefor LLM-based naming via backgroundtokio::spawn- Passes
auto_archive_durationthrough to thread creation - Updates Helm chart + config.toml.example
3. What was considered?
Per-channel overrides with global defaults (good layering), background thread naming with 10s timeout, input truncation for naming prompt.
4. Is it the best approach?
Design concepts are sound, but implementation targets a codebase that no longer exists.
Traffic Light
🟢 INFO
- Config validation at startup with clear error messages — excellent fail-fast pattern
- Per-channel override pattern is well-designed
- Background thread naming with timeout is the right pattern
🔴 SUGGESTED CHANGES
- Structurally incompatible with current main — Targets pre-refactor architecture. Not a simple rebase — requires reimplementation against
AdapterRouter/ChatAdapterpattern. generate_thread_namereuses session pool connection — Sends naming prompt through same ACP session, polluting conversation history. Should use separate ephemeral session.- Thread name flash — Thread created with truncated name first, then renamed in background. Creates visible flash.
🟡 NIT
thread_name_modeas String instead of enum — properThreadNameModeenum would be more idiomatic Rust- Helm template boolean handling should use
hasKeypattern (PR #639)
Recommendation: Close this PR. If the contributor wants to pursue these features, they should open a new PR based on current main and implement against the AdapterRouter/ChatAdapter pattern.
Reviewed by 超渡法師 🔃 chaodu Backlog triage
|
Closing — main has undergone major architectural refactoring (AdapterRouter/ChatAdapter abstraction) since this PR was opened. The feature concepts (auto-archive duration, per-channel config, LLM thread naming) are still valuable but would need to be reimplemented against the current architecture. Thanks for the contribution! 🙏 |
Summary
Inspired by OpenClaw Discord Workflow, adds advanced thread management features to improve the Discord experience for multi-user environments.
Closes #188
New Features
auto_archive_durationto 60 (1h), 1440 (1d), 4320 (3d), or 10080 (1w). Previously hardcoded to 1 day.[discord.channels."<ID>"]sections in config.require_mention = false) — Any message in the channel triggers a thread, no @mention needed. Ideal for dedicated bot channels.ignore_other_mentions = true) — Skip messages that mention other bots/users but not this bot. Prevents false triggers in multi-bot environments.thread_name_mode = "generated") — After the main prompt completes, a background task asks the agent for a short title and renames the thread. Falls back to truncated name on failure (10s timeout).Config Example
Files Changed
src/config.rs—ChannelConfigstruct, new fields onDiscordConfig, validationsrc/discord.rs— Per-channel config resolution, direct mode, ignore logic, background thread namingsrc/main.rs— Pass new config fields to Handlerconfig.toml.example— Document all new optionscharts/openab/values.yaml— Helm values for new settingscharts/openab/templates/configmap.yaml— Template per-channel configKnown Limitations
with_connectionholds a global write lock during the naming request. Under high concurrent load withthread_name_mode = "generated", this may cause brief stalls for other threads.Test plan
auto_archive_duration = 60— verify threads archive after 1 hourrequire_mention = falseon a channel — verify any message creates a threadignore_other_mentions = true— verify messages mentioning other bots are skippedthread_name_mode = "generated"— verify thread gets renamed after first responseauto_archive_duration = 999) — verify startup fails with clear errorhelm templatewith new values — verify configmap output is correct🤖 Generated with Claude Code